package com.sisucc.contractmanage.serviceImpl.staffSettingServiceImpl;

import cn.hutool.core.util.StrUtil;
import com.sisucc.contractmanage.bean.ResultModel;
import com.sisucc.contractmanage.bean.accountInfo.AccountInfoBean;
import com.sisucc.contractmanage.bean.assistInfo.AssistInfoBean;
import com.sisucc.contractmanage.bean.staffInfo.StaffInfoBean;
import com.sisucc.contractmanage.constant.ConstantDataType;
import com.sisucc.contractmanage.constant.ReturnStatusCode;
import com.sisucc.contractmanage.dao.accountInfo.AccountInfoRepository;
import com.sisucc.contractmanage.dao.assistInfo.AssistInfoRepository;
import com.sisucc.contractmanage.dao.staffInfo.StaffInfoRepository;
import com.sisucc.contractmanage.service.staffSettingService.StaffSettingService;
import com.sisucc.contractmanage.util.LocalDateTimeUtil;
import com.sisucc.contractmanage.util.PropertyUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author linyuqi
 */
@Log4j2
@Service
@Transactional
public class StaffSettingServiceImpl implements StaffSettingService {

    @Autowired
    private StaffInfoRepository repository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AccountInfoRepository accountInfoRepository;

    @Autowired
    private AssistInfoRepository assistInfoRepository;

    @Override
    public ResultModel queryStaffSettingInfo(Map<String, Object> params) throws ParseException {
        ResultModel model = new ResultModel();
        String staffCodeParam = params.get("staffCodeParam").toString();
        String staffNameParam = params.get("staffNameParam").toString();
        String startTimeParamSnap = params.get("startTimeParam").toString();
        String endTimeParamSnap = params.get("endTimeParam").toString();
        String accountStatusDropdownParam = params.get("accountStatusDropdownParam").toString();
        String departDropdownParam = params.get("departDropdownParam").toString();
        int currentPage = Integer.parseInt(params.get("currentPage").toString());
        int pageSize = Integer.parseInt(params.get("pageSize").toString());
        LocalDateTime startTimeParam = null;
        LocalDateTime endTimeParam = null;
        if (StrUtil.isNotBlank(startTimeParamSnap)) {
            startTimeParam = LocalDateTimeUtil.GMTToLocalDateTime(PropertyUtil.getStartTimeString(startTimeParamSnap));
        }
        if (StrUtil.isNotBlank(endTimeParamSnap)) {
            endTimeParam = LocalDateTimeUtil.GMTToLocalDateTime(PropertyUtil.getEndTimeString(endTimeParamSnap));
        }
        try {
            LocalDateTime finalStartTimeParam = startTimeParam;
            LocalDateTime finalEndTimeParam = endTimeParam;
            Specification<StaffInfoBean> specification =
                    (Specification<StaffInfoBean>) (root, criteriaQuery, criteriaBuilder) -> {
                        List<Predicate> predicates = new ArrayList<>();
                        if (StrUtil.isNotBlank(staffCodeParam)) {
                            predicates.add(criteriaBuilder.like(root.get("staffCode"), "%" + staffCodeParam + "%"));
                        }
                        if (StrUtil.isNotBlank(staffNameParam)) {
                            predicates.add(criteriaBuilder.like(root.get("staffName"), "%" + staffNameParam + "%"));
                        }
                        if (Optional.ofNullable(finalStartTimeParam).isPresent()) {
                            predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), finalStartTimeParam));
                        }
                        if (Optional.ofNullable(finalEndTimeParam).isPresent()) {
                            predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), finalEndTimeParam));
                        }
                        if (StrUtil.isNotBlank(accountStatusDropdownParam)) {
                            predicates.add(criteriaBuilder.equal(root.get("accountStatus"), accountStatusDropdownParam));
                        }
                        if (StrUtil.isNotBlank(departDropdownParam)) {
                            predicates.add(criteriaBuilder.equal(root.get("departId"), departDropdownParam));
                        }
                        Predicate[] array = new Predicate[predicates.size()];
                        return criteriaBuilder.and(predicates.toArray(array));
                    };
            Page<StaffInfoBean> systemSettingBeanPage =
                    repository.findAll(specification,
                            PageRequest.of(currentPage, pageSize,
                                    Sort.by(Sort.Direction.DESC, "createTime")));
            model.getResultMap().put("total", systemSettingBeanPage.getTotalElements());
            model.getResultMap().put("pages", systemSettingBeanPage.getTotalPages());
            model.setResultList(systemSettingBeanPage.getContent());
            log.info("查询所有职员信息---列表：" + systemSettingBeanPage.getContent().toString());
            log.info("查询所有职员信息---总数：" + systemSettingBeanPage.getTotalElements());
            log.info("查询所有职员信息---页数：" + systemSettingBeanPage.getTotalPages());
        } catch (Exception e) {
            e.printStackTrace();
            model.setStatusCode(ReturnStatusCode.ERROR);
            model.setResultMessage(ReturnStatusCode.ERROR_MESSAGE);
            log.info("查询所有职员信息---程序执行失败！");
        }
        return model;
    }

    @Override
    public ResultModel saveStaffSettingInfo(Map<String, Object> params) {
        ResultModel model = new ResultModel();
        String uuid = PropertyUtil.getUUID();
        String staffCode = (String) params.get("staffCode");
        String staffName = (String) params.get("staffName");
        String departId = (String) params.get("departId");
        String loginAccount = (String) params.get("loginAccount");
        String loginPassword = (String) params.get("loginPassword");
        String accountStatus = (String) params.get("accountStatus");
        LocalDateTime currentDateTime = PropertyUtil.getCurrentDateTime();
        AssistInfoBean departInfo = assistInfoRepository.findById(departId).get();
        try {
            StaffInfoBean staffInfoBean = new StaffInfoBean(uuid, staffCode, staffName, "", departId, departInfo.getInfoName(),
                    accountStatus, currentDateTime, null);
            log.info("添加新的职员信息" + staffInfoBean.toString());
            AccountInfoBean accountInfoBean = new AccountInfoBean(uuid, loginAccount, passwordEncoder.encode(loginPassword),
                    currentDateTime, null);
            log.info("新的职员的登陆信息" + accountInfoBean.toString());
            repository.save(staffInfoBean);
            accountInfoRepository.save(accountInfoBean);
        } catch (Exception e) {
            e.printStackTrace();
            model.setStatusCode(ReturnStatusCode.ERROR);
            model.setResultMessage(ReturnStatusCode.ERROR_MESSAGE);
            log.info("添加新的职员信息---程序执行失败！");
        }
        return model;
    }

    @Override
    public ResultModel modifyStaffSettingInfo(Map<String, Object> params) {
        ResultModel model = new ResultModel();
        String staffInfoId = (String) params.get("staffInfoId");
        String staffCode = (String) params.get("staffCode");
        String staffName = (String) params.get("staffName");
        String departId = (String) params.get("departId");
        String loginAccount = (String) params.get("loginAccount");
        String loginPassword = (String) params.get("loginPassword");
        String accountStatus = (String) params.get("accountStatus");
        LocalDateTime currentDateTime = PropertyUtil.getCurrentDateTime();
        AssistInfoBean departInfo = assistInfoRepository.findById(departId).get();
        try {
            StaffInfoBean staffInfoBean = new StaffInfoBean(staffInfoId, staffCode, staffName, "", departId, departInfo.getInfoName(),
                    accountStatus, currentDateTime, null);
            log.info("修改职员信息" + staffInfoBean.toString());
            AccountInfoBean accountInfoBean = new AccountInfoBean(staffInfoId, loginAccount, loginPassword,
                    currentDateTime, null);
            log.info("修改职员的登陆信息" + accountInfoBean.toString());
            repository.save(staffInfoBean);
            accountInfoRepository.save(accountInfoBean);
        } catch (Exception e) {
            e.printStackTrace();
            model.setStatusCode(ReturnStatusCode.ERROR);
            model.setResultMessage(ReturnStatusCode.ERROR_MESSAGE);
            log.info("修改职员信息---程序执行失败！");
        }
        return model;
    }

    @Override
    public ResultModel deleteStaffSettingInfo(Map<String, Object> params) {
        ResultModel model = new ResultModel();
        String staffSettingId = (String) params.get("staffSettingId");
        try {
            /**
             * to-do 判断当前部门是否还有人
             */
            log.info("删除职员信息" + staffSettingId);
            repository.deleteById(staffSettingId);
        } catch (Exception e) {
            e.printStackTrace();
            model.setStatusCode(ReturnStatusCode.ERROR);
            model.setResultMessage(ReturnStatusCode.ERROR_MESSAGE);
            log.info("删除职员信息---程序执行失败！");
        }
        return model;
    }

    @Override
    public ResultModel queryStaffSettingInfoById(Map<String, Object> params) {
        ResultModel model = new ResultModel();
        String staffSettingId = (String) params.get("staffSettingId");
        try {
            /**
             * to-do 判断当前部门是否还有人
             */
            log.info("查询职员ID信息" + staffSettingId);
            Optional<StaffInfoBean> staffInfo = repository.findById(staffSettingId);
            String accountCode = accountInfoRepository.findById(staffSettingId).get().getAccountCode();
            model.getResultMap().put("staffInfo", staffInfo);
            model.getResultMap().put("accountCode", accountCode);
        } catch (Exception e) {
            e.printStackTrace();
            model.setStatusCode(ReturnStatusCode.ERROR);
            model.setResultMessage(ReturnStatusCode.ERROR_MESSAGE);
            log.info("查询职员信息---程序执行失败！");
        }
        return model;
    }

    @Override
    public ResultModel verifyLoginAccount(Map<String, Object> params) {
        ResultModel model = new ResultModel();
        String loginAccount = (String) params.get("loginAccount");
        try {
            log.info("当前账号信息" + loginAccount);
            AccountInfoBean accountInfoBean = accountInfoRepository.findByAccountCode(loginAccount);
            if (!Optional.ofNullable(accountInfoBean).isPresent()) {
                model.getResultMap().put("status", ReturnStatusCode.SUCCESS_CODE);
            } else {
                model.getResultMap().put("status", ReturnStatusCode.ERROR_CODE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            model.setStatusCode(ReturnStatusCode.ERROR);
            model.setResultMessage(ReturnStatusCode.ERROR_MESSAGE);
            log.info("查询职员信息---程序执行失败！");
        }
        return model;
    }

    @Override
    public String init() {
        String staffCode = "admin";
        String password = "1234";
        String message = "Admin init successful!";
        String uuid = PropertyUtil.getUUID();
        LocalDateTime currentDateTime = PropertyUtil.getCurrentDateTime();
        StaffInfoBean staffInfoBean = new StaffInfoBean(uuid, staffCode, staffCode, "", "000000", "默认", "0", currentDateTime, null);
        AccountInfoBean accountInfoBean = new AccountInfoBean(uuid, staffCode, passwordEncoder.encode(password), currentDateTime, null);
        AssistInfoBean defaultDepart = new AssistInfoBean(PropertyUtil.getUUID(), "000000", "默认", ConstantDataType.DEPARTMENT, PropertyUtil.getCurrentDateTime());
        AssistInfoBean defaultContractType = new AssistInfoBean(PropertyUtil.getUUID(), "000000", "默认", ConstantDataType.CONTRACT_TYPE, PropertyUtil.getCurrentDateTime());
        try {
            repository.save(staffInfoBean);
            accountInfoRepository.save(accountInfoBean);
            assistInfoRepository.save(defaultDepart);
            assistInfoRepository.save(defaultContractType);
        } catch (Exception e) {
            message = "Admin init failed!";
            log.info("admin用户初始化失败：" + e.toString());
        }
        return message;
    }
}
